package com.promise.jokerdream.work.knight.Arena

import com.promise.jokerdream.config.game.KnightArenaFormation
import com.promise.jokerdream.database.entity.KnightArenaGameConfigEntity
import com.promise.jokerdream.manager.ExecutionHistoryManager
import com.promise.jokerdream.repository.GameApi
import com.promise.jokerdream.repository.PhoneGameApi
import com.promise.jokerdream.repository.foldWithApiException
import com.promise.jokerdream.response.pc.QueryKnightArenaResponse
import com.promise.jokerdream.utils.AppContext
import com.promise.jokerdream.work.BaseWork
import com.promise.jokerdream.work.WorkResult
import kotlinx.coroutines.delay

// 侠士论剑工作
class KnightArenaWork(
    private val config: KnightArenaGameConfigEntity,
    uin: String
): BaseWork(uin) {

    override val name: String
        get() = "论剑"

    private val gameApi = GameApi.getInstance()
    private val phoneGameApi = PhoneGameApi.getInstance()
    private val historyManager by lazy { ExecutionHistoryManager.getInstance(AppContext.get()) }

    override suspend fun executeWork(): WorkResult {
        return try {
            // 查询侠士论剑状态
            val queryResult = gameApi.queryKnightArena()
            queryResult.foldWithApiException(
                onSuccess = { arenaInfo ->

                    // 检查是否可以挑战：剩余次数大于0
                    if (arenaInfo.nextSeasonTime == -1 && arenaInfo.leftFreeTimes > 0) {
                        // 直接挑战
                        executeChallengeLoop(arenaInfo)
                    }
                    
                    WorkResult.Success
                },
                onFailure = { code, msg ->
                    historyManager.addHistory(name, msg, code)
                    WorkResult.Failure(Exception(msg), msg)
                }
            )
        } catch (e: Exception) {
            historyManager.addHistory(name, e.message)
            WorkResult.Failure(e, e.message)
        }
    }

    
    /**
     * 执行挑战循环，根据剩余次数挑战
     * @param arenaInfo 侠士论剑信息
     * @return 是否有发生挑战
     */
    private suspend fun executeChallengeLoop(arenaInfo: QueryKnightArenaResponse): WorkResult {
        if (arenaInfo.leftFreeTimes <= 0) {
            return WorkResult.Success
        }
        // 从 JSON 解析阵容列表
        val formations = if (config.formationsJson.isEmpty()) {
            emptyList()
        } else {
            try {
                val json = kotlinx.serialization.json.Json { ignoreUnknownKeys = true; encodeDefaults = true }
                json.decodeFromString<List<com.promise.jokerdream.config.game.KnightArenaFormation>>(config.formationsJson)
            } catch (e: Exception) {
                emptyList()
            }
        }
        
        // 检查是否有配置的阵容
        if (formations.isEmpty()) {
            return WorkResult.Success
        }
        
        // 计算已经挑战的次数
        val maxDailyChallenges = formations.sumOf { it.challengeCount }
        val alreadyChallenged = maxDailyChallenges - arenaInfo.leftFreeTimes
        var currentChallengeIndex = 0
        
        // 遍历所有配置的阵容
        for (formation in formations) {
            if (formation.knights.isEmpty()) continue
            
            // 计算当前阵容应该挑战的次数
            val formationStartIndex = currentChallengeIndex
            val formationEndIndex = currentChallengeIndex + formation.challengeCount
            
            // 如果这个阵容的挑战范围还没有开始，跳过
            if (formationEndIndex <= alreadyChallenged) {
                currentChallengeIndex = formationEndIndex
                continue
            }
            
            // 如果这个阵容的挑战范围已经全部完成，跳过
            if (formationStartIndex >= alreadyChallenged + arenaInfo.leftFreeTimes) {
                break
            }
            
            // 设置侠士阵容
            setupKnightFormation(formation)
            
            // 计算当前阵容实际需要挑战的次数
            val startChallengeIndex = maxOf(formationStartIndex, alreadyChallenged)
            val endChallengeIndex = minOf(formationEndIndex, alreadyChallenged + arenaInfo.leftFreeTimes)
            val challengeCount = endChallengeIndex - startChallengeIndex
            
            if (challengeCount <= 0) {
                currentChallengeIndex = formationEndIndex
                continue
            }
            
            // 执行挑战
            for (i in 1..challengeCount) {
                val challengeResult = phoneGameApi.fightKnightArena()
                challengeResult.foldWithApiException(
                    onSuccess = { response ->
                        historyManager.addHistory(name, response.actionResult)
                    },
                    onFailure = { code, msg ->
                        historyManager.addHistory(name, msg, code)
                    }
                )
            }
            
            currentChallengeIndex = formationEndIndex
        }
        
        return WorkResult.Success
    }

    /**
     * 设置侠士阵容
     */
    private suspend fun setupKnightFormation(formation: KnightArenaFormation) {
        // 直接设置侠士阵容
        for ((index, knight) in formation.knights.withIndex()) {
            if (index >= 3) break // 最多3个位置
            
            var retryCount = 0
            val maxRetries = 3
            
            while (retryCount < maxRetries) {
                val replaceResult = gameApi.replaceKnightArenaKnight(index, knight.id)
                replaceResult.foldWithApiException(
                    onSuccess = { response ->
                        historyManager.addHistory(name, "设置侠士${index+1}: ${knight.name}")
                        retryCount = maxRetries // 成功时跳出重试循环
                    },
                    onFailure = { code, msg ->
                        retryCount++
                        historyManager.addHistory(name, msg, code)
                        
                        if (retryCount < maxRetries) {
                            delay(500)
                        }
                    }
                )
            }
        }
    }
}